#include <app.h>

typedef struct
{
    VU32 CTRL;
    VU32 LOAD;
    VU32 VAL;
    VU32 CALIB;
} SysTick_Type;

#define SysTick                    ((SysTick_Type*)0xE000E010UL)

#define SysTick_CTRL_CLKSOURCE_Pos 2
#define SysTick_CTRL_TICKINT_Pos   1
#define SysTick_CTRL_ENABLE_Pos    0

#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos)
#define SysTick_CTRL_TICKINT_Msk   (1UL << SysTick_CTRL_TICKINT_Pos)
#define SysTick_CTRL_ENABLE_Msk    (1UL << SysTick_CTRL_ENABLE_Pos)

/*
 * core clock is 8M, 16M, 25M...
 * so freq is based on us
 */
U32 event_handler_systick(U32 ip, U32 cmd, U32 param1, U32 param2)
{
    U32 core_freq;
    U32 freq;
    U32 count;

    switch (cmd)
    {
    case SWIP_CMD_ENABLE:
        freq      = param1;
        core_freq = swip_call(SWIP_SOC_CLOCK, SWIP_CMD_CLOCK_GET, SWIP_SOC_CORE, 0);
        count     = core_freq / freq;

        SysTick->LOAD = count - 1;
        SysTick->VAL  = 0;
        SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
                        SysTick_CTRL_TICKINT_Msk |
                        SysTick_CTRL_ENABLE_Msk;
        // TODO: default priority SHOULD be 15 (in core_cm4.h)
        break;
    }

    return 0;
}
